package mutris.client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.util.Observable;
import java.util.Observer;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

import mutris.client.board.BlockGroup;
import mutris.client.board.BlockPoint;
import mutris.client.board.Board;
import mutris.client.com.AppMenuBar;
import mutris.client.com.MutrisPanel;
import mutris.client.handlers.BoardKeyHandler;

public class MutrisFrame extends JFrame {

	
	private MutrisGame game;
	private Board previewBoard;
	
	public MutrisFrame() {
		super("Mutris");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(new BorderLayout());
		
		game = new MutrisGame();
		
		setJMenuBar(new AppMenuBar(game));
		
		add(getGamePanel(), BorderLayout.CENTER);
		add(getPreviewPanel(), BorderLayout.EAST);
		
		addKeyListener(new BoardKeyHandler(game));
		
		setResizable(false);
		setSize(420, 600);
	}
	
	
	private JComponent getGamePanel() {
		JPanel panel = new JPanel(new BorderLayout());
		panel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
		
		MutrisPanel mutrisPanel = new MutrisPanel(game.getBoard());
		
		JPanel groovePanel = new JPanel(new BorderLayout());
		groovePanel.setBorder(BorderFactory.createLoweredBevelBorder());
		groovePanel.add(mutrisPanel, BorderLayout.CENTER);

		panel.add(groovePanel, BorderLayout.CENTER);

		return panel;
	}
	
	private JComponent getPreviewPanel() {
		previewBoard = new Board(7, 7);
		
		MutrisPanel mutrisPanel = new MutrisPanel(previewBoard);
		
		JPanel panel = new JPanel(new BorderLayout());
		panel.setBorder(BorderFactory.createEmptyBorder(8, 0, 8, 8));
		
		JPanel previewPanel = new JPanel(new BorderLayout());
		previewPanel.setBorder(BorderFactory.createLoweredBevelBorder());
		previewPanel.add(mutrisPanel, BorderLayout.NORTH);
		
		game.getBoard().addObserver(new Observer() {
			@Override
			public void update(Observable o, Object arg) {
				if (arg instanceof MutrisGame.GameInfo) {
					MutrisGame.GameInfo gameInfo = (MutrisGame.GameInfo) arg;
					BlockGroup blocks = gameInfo.getNextBlocks();
					
					previewBoard.clearBlocks();
					
					if (null != blocks) {
						int x = (int) Math.ceil(3.5f - (blocks.getWidth() / 2f));
						int y = (int) Math.floor(3.5f - (blocks.getHeight() / 2f));
						
						for (BlockPoint p : blocks.getPoints()) {
							previewBoard.setBlock(x + p.x, y + p.y, blocks.getBlock(p));
						}
						
						previewBoard.notifyObservers();
					}
				}
			}
		});
		
		mutrisPanel.setPreferredSize(new Dimension(100, 100));
		
		panel.add(previewPanel, BorderLayout.NORTH);
		panel.add(getGameScorePanel(), BorderLayout.EAST);
		
		return panel;
	}
	
	public JComponent getGameScorePanel() {
		JPanel panel = new JPanel(new BorderLayout());
		panel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));

		JPanel infoPanel = new JPanel(new GridLayout(6, 1));
		infoPanel.setPreferredSize(new Dimension(100, 160));
		infoPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
		infoPanel.setBackground(Color.black);
		infoPanel.setForeground(Color.white);
		infoPanel.setFont(new Font(infoPanel.getFont().getFamily(), 14, Font.PLAIN));

		JLabel lblLevelLabel = new JLabel("Level");
		lblLevelLabel.setForeground(Color.white);
		final JLabel lblLevel = new JLabel("--");
		lblLevel.setHorizontalAlignment(SwingConstants.CENTER);
		lblLevel.setForeground(Color.GREEN);
		
		JLabel lblLinesLabel = new JLabel("Lines");
		lblLinesLabel.setForeground(Color.white);
		final JLabel lblLines = new JLabel("--");
		lblLines.setHorizontalAlignment(SwingConstants.CENTER);
		lblLines.setForeground(Color.GREEN);
		
		JLabel lblBLocksLabel = new JLabel("Blocks");
		lblBLocksLabel.setForeground(Color.white);
		final JLabel lblBlocks = new JLabel("--");
		lblBlocks.setHorizontalAlignment(SwingConstants.CENTER);
		lblBlocks.setForeground(Color.GREEN);

		infoPanel.add(lblLevelLabel);
		infoPanel.add(lblLevel);
		infoPanel.add(lblBLocksLabel);
		infoPanel.add(lblBlocks);
		infoPanel.add(lblLinesLabel);
		infoPanel.add(lblLines);

		
		JPanel groovePanel = new JPanel(new BorderLayout());
		groovePanel.setBorder(BorderFactory.createLoweredBevelBorder());
		groovePanel.add(infoPanel, BorderLayout.CENTER);
		
		panel.add(groovePanel, BorderLayout.NORTH);
		
		game.getBoard().addObserver(new Observer() {
			@Override
			public void update(Observable o, Object arg) {
				if (arg instanceof MutrisGame.GameInfo) {
					MutrisGame.GameInfo gameInfo = (MutrisGame.GameInfo) arg;
					
					lblLevel.setText(gameInfo.getLevel() == 0 ? "--" : Integer.toString(gameInfo.getLevel()));
					lblLines.setText(gameInfo.getLineCount() == 0 ? "--" : Integer.toString(gameInfo.getLineCount()));
					lblBlocks.setText(gameInfo.getBlockCount() == 0 ? "--" : Integer.toString(gameInfo.getBlockCount()));
				}
			}
		});
		
		return panel;
	}
	
	
	public MutrisGame getGame() {
		return game;
	}
	
}
